﻿//#define _CRT_SECURE_NO_WARNINGS
//#include <stdio.h>

#include "common.h"

int my_strlen(char* str)
{ // 指针减指针
	char* p = str;
	while (*p++ != '\0');
	return p - str;
}

void print_array_pointer(int** arr, int rows, int cols)
{ // 对于指针数组，这里的 int** arr 等价于 int (*arr)[cols] 注意 cols 必须写为整数值
	int i, j;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
			printf("%d ", *(*(arr + i) + j));
		//printf("%d ", arr[i][j]);
		printf("\n");
	}
}

void print_2d_array(int (*p)[4], int rows, int cols)
{  // 这里的 p 是二维数组的指针，指向数组首数组的地址
	/*	p 的类型是 int (*)[4]
		p 指向 int [4] 的整型数组
		p + 1 跳过 int [4] 个字节 */
		//对于这种非指针数组的二维数组，不能写为 int** p，必须写为 int (*p)[4]
	int i, j;
	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
			//printf("%d ", *(*(p + i) + j));
			printf("%d ", p[i][j]);
		printf("\n");
	}
}

// 函数式编程，黑框框实现简单计算器的加减乘除
void clean_console()
{
	while (getchar() != '\n');
}// 清空输入缓冲区

void calculate_menu()
{
	printf("****************************\n");
	printf("****** 1.加法计算器 *********\n");
	printf("****** 2.减法计算器 *********\n");
	printf("****** 3.乘法计算器 *********\n");
	printf("****** 4.除法计算器 *********\n");
	printf("****** 5.按位与计算 *********\n");
	printf("****** 6.按位或计算 *********\n");
	printf("****** 7.位异或计算 *********\n");
	printf("******  8.按位取反  *********\n");
	printf("****** 0.退出计算器 *********\n");
	printf("****************************\n");
}

float calculate_add(float a, float b)
{
	return a + b;
}

float calculate_sub(float a, float b)
{
	return a - b;
}

float calculate_mul(float a, float b)
{
	return a * b;
}

float calculate_div(float a, float b)
{
	return a / b;
}

// 添加位操作功能
int post_and(int a, int b)
{
	return a & b;
}

int post_or(int a, int b)
{
	return a | b;
}

int post_xor(int a, int b)
{
	return a ^ b;
}

int post_reverse(int a)
{
	return ~a;
}

// 回调函数学习示例
void calculate_print_result(float (*op)(float, float))
{
	float a, b;
	printf("请输入两个需要计算的数(空格分开)：");
	int input_num = scanf("%f %f", &a, &b);
	clean_console();
	printf("计算结果为：%.2f\n", (*op)(a, b));// 打印调用回调函数的结果
}

void calculate_post_print_result(int (*op)(int, int))
{
	int a, b;
	printf("请输入两个需要按位计算的整数(空格分开)：");
	int input_num = scanf("%d %d", &a, &b);
	clean_console();
	printf("计算结果为：%d\n", (*op)(a, b));// 打印调用回调函数的结果
}

void calculate_main()
{
	int choice;
	do
	{
		calculate_menu();
		printf("请选择计算方式：");
		int input_choice = scanf("%d", &choice);
		clean_console();
		int (*arr_func[8])(int, int) = { // 函数指针数组
			0, 0, 0, 0, 0, &post_and, &post_or, &post_xor };
		if (choice >= 5 && choice <= 7)
			calculate_post_print_result(arr_func[choice]);
		else if (8 == choice)
		{
			int a;
			printf("请输入一个需要按位取反的整数：");
			int input_num = scanf("%d", &a);
			clean_console();
			printf("计算结果为：%d\n", post_reverse(a));// 打印调用回调函数的结果
		}
		else
		{
			switch (choice)
			{
			case 1:
				calculate_print_result(&calculate_add);
				break;
			case 2:
				calculate_print_result(&calculate_sub);
				break;
			case 3:
				calculate_print_result(&calculate_mul);
				break;
			case 4:
				calculate_print_result(&calculate_div);
				break;
			case 0:
				break;
			default:
				printf("输入错误，请重新输入！\n");
				break;
			}
		}
	} while (choice);
}

void calculate()  // 本文件单独使用时，改为 main
{
	calculate_main();
}
